/*
*   @Author: 1296
*   @Date: 2025-03-26
*   @Description: 滑块验证码
*/

<!--用法-->
<!--<template>-->
<!--  <SliderVerification :next-url="PATH" />-->
<!--</template>-->

<!--<script setup>-->
<!--import SliderVerification from "@/components/verification/SliderVerification.vue";-->
<!--const PATH = "/"-->
<!--</script>-->


<script setup>
/* global defineProps, defineEmits */
import {ref, computed, onUnmounted, onMounted} from 'vue'
import {useI18n} from "vue-i18n";
import router from "@/router";
const {t} = useI18n();
const props = defineProps({
  nextUrl: {
    type: String,
    default: "/"
  },
  width: { type: Number, default: 300 },
  height: { type: Number, default: 40 },
  tipText: { type: String, default: "" },
  successText: { type: String, default: "" },
  targetPosition: { type: Number, default: 85 }
})

const emit = defineEmits(['verification-success'])

const sliderContainer = ref(null)
const isDragging = ref(false)
const currentX = ref(0)
const success = ref(false)
const normalizedTipText = computed(() =>
    props.tipText || t('SliderVerify')
)
const normalizedSuccessText = computed(() =>
    props.successText || t('VerifySuccess')
)

const trackStyle = computed(() => ({
  width: `${props.width}px`,
  height: `${props.height}px`,
  borderRadius: `${props.height / 2}px`
}))

const sliderStyle = computed(() => ({
  left: `${currentX.value}px`,
  transition: isDragging.value ? 'none' : 'left 0.3s ease'
}))

const fillStyle = computed(() => ({
  width: `${currentX.value + 40}px`,
  backgroundColor: success.value ? '#52c41a' : '#1890ff'
}))



const startDrag = (e) => {
  if (success.value) return
  isDragging.value = true

  const initClientX = e.clientX ??
      (e.touches?.[0]?.clientX ?? 0)
  handleMove(initClientX)
}

const handleMove = (clientX) => {
  if (!isDragging.value || !sliderContainer.value) return
  const rect = sliderContainer.value.getBoundingClientRect()
  let newX = clientX - rect.left - 20
  newX = Math.max(0, Math.min(newX, props.width - 40))
  currentX.value = newX < 5 ? 0 : newX
}

const endDrag = () => {
  if (!isDragging.value) return
  isDragging.value = false

  const target = props.width * (props.targetPosition / 100)
  const threshold = props.width * 0.03

  if (Math.abs(currentX.value - target) < threshold) {
    success.value = true
    currentX.value = target
    setTimeout(() => {
      emit('verification-success')
      router.push(props.nextUrl)
    }, 1000)
  } else {
    currentX.value = 0
  }
}

const handleEvents = {
  move: (e) => {
    const isTouch = e.type.startsWith('touch')
    const clientX = isTouch ?
        (e.touches?.[0]?.clientX ?? 0) :
        e.clientX
    handleMove(clientX)
  },
  end: () => endDrag()
}

const addListeners = () => {
  document.addEventListener('mousemove', handleEvents.move)
  document.addEventListener('mouseup', handleEvents.end)
  document.addEventListener('touchmove', handleEvents.move)
  document.addEventListener('touchend', handleEvents.end)
}

const removeListeners = () => {
  document.removeEventListener('mousemove', handleEvents.move)
  document.removeEventListener('mouseup', handleEvents.end)
  document.removeEventListener('touchmove', handleEvents.move)
  document.removeEventListener('touchend', handleEvents.end)
}

onMounted(addListeners)
onUnmounted(removeListeners)
</script>

<template>
  <div class="slider-verification">
    <div
        ref="sliderContainer"
        class="slider-track"
        :style="trackStyle"
        @mousedown.prevent="startDrag"
        @touchstart.prevent="startDrag"
    >
      <div class="slider-fill" :style="fillStyle"></div>
      <div
          class="slider-button"
          :style="sliderStyle"
          :class="{ success: success }"
      >
        <span v-if="!success">→</span>
        <span v-else>✓</span>
      </div>

      <div class="slider-text">
        {{ success ? normalizedSuccessText : normalizedTipText }}
      </div>
    </div>
  </div>
</template>

<style scoped>
.slider-verification {
  user-select: none;
  touch-action: none;
}

.slider-track {
  position: absolute;
  left: 0;
  top: 0;
  right: 0;
  bottom: 0;
  margin: auto;
  background-color: #f5f5f5;
  box-shadow: inset 0 1px 3px rgba(0,0,0,0.1);
}

.slider-fill {
  position: absolute;
  left: 0;
  height: 100%;
  border-radius: inherit;
  transform: translateZ(0);
  will-change: width;
}

.slider-button {
  position: absolute;
  top: 0;
  width: 40px;
  height: 40px;
  background-color: white;
  border-radius: 50%;
  box-shadow: 0 2px 4px rgba(0,0,0,0.2);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: grab;
  z-index: 1;
  transition: left 0.1s linear;
}

.slider-button:active {
  cursor: grabbing;
}

.slider-button.success {
  background-color: #52c41a;
  color: white;
}

.slider-text {
  position: absolute;
  width: 100%;
  top: 50%;
  transform: translateY(-50%);
  text-align: center;
  color: #666;
  font-size: 14px;
  pointer-events: none;
  z-index: 0;
}
</style>